package com.lcw.android.scrollsplitview.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;

/**
 * @author lcw
 * @date 2021/3/22
 * @desc 垂直抽屉控制布局
 */
public class VerticalDrawerControlLayout extends ViewGroup implements View.OnTouchListener {

    private View mTop, mBottom, mDrawer;
    private Drawable mBottomBackground;
    private int mBottomBackgroundColor = Color.parseColor("#585858");
    private int mScrollHeight;
    private int mTouchSlop;
    private int mLastMotionY = 0;

    public VerticalDrawerControlLayout(Context context) {
        this(context, null);
    }

    public VerticalDrawerControlLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerticalDrawerControlLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    protected void setupViews() {
        mBottom = getChildAt(0);
        mDrawer = getChildAt(1);
        mTop = getChildAt(2);

        mBottomBackground = mBottom.getBackground(); // 记录mBottom原来的背景，方便后面还原
        mDrawer.setOnTouchListener(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (getChildCount() != 3) {
            throw new RuntimeException("give 3 views");
        }
        //measure child
        measureChildren(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        l = t = 0;
        mTop.layout(l, t, l + mTop.getMeasuredWidth(), t + mTop.getMeasuredHeight());
        if (mTop.getMeasuredHeight() + mBottom.getMeasuredHeight() > getMeasuredHeight()) {
            mBottom.layout(l, t + mTop.getMeasuredHeight(), l + mBottom.getMeasuredWidth(), t + mBottom.getMeasuredHeight());
        } else {
            mBottom.layout(l, t + mTop.getMeasuredHeight(), l + mBottom.getMeasuredWidth(), t + mTop.getMeasuredHeight() + mBottom.getMeasuredHeight());
        }
        mDrawer.layout(l, t + mScrollHeight + mTop.getMeasuredHeight() - mDrawer.getMeasuredHeight(), l + mDrawer.getMeasuredWidth(), t + mScrollHeight + mTop.getMeasuredHeight());
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        setupViews();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastMotionY = (int) event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
                int delta = (int) (event.getY() - mLastMotionY);
                if (Math.abs(delta) > mTouchSlop) {
                    if (delta > 0) {
                        mScrollHeight += delta - mTouchSlop;
                    } else {
                        mScrollHeight += delta + mTouchSlop;
                    }

                    if (mScrollHeight < 0) {
                        mScrollHeight = 0;
                    }
                    if (mScrollHeight > mDrawer.getHeight()) {
                        mScrollHeight = mDrawer.getHeight();
                    }

                    float scroll = (float) mScrollHeight / mDrawer.getHeight();
                    mBottom.setBackgroundColor(mBottomBackgroundColor);
                    mBottom.getBackground().setAlpha((int) (scroll * 255));
                    if (mDragCallback != null) {
                        mDragCallback.onDrag(scroll);
                    }
                    Log.e("changwen", "mScrollHeight = " + mScrollHeight);
                    // mScrollHeight 改变之后重绘
                    requestLayout();
                }
                return true;
            case MotionEvent.ACTION_UP:
                // 松开手指，展开超过一半，就完全展开，否则完全折叠收起
                if (mScrollHeight > mDrawer.getHeight() * 0.5) {
                    openDrawerNoAnim();
                } else {
                    closeDrawerNoAnim();
                }
                requestLayout();
                return true;
        }
        return false;
    }

    /**
     * 打开抽屉
     */
    public void openDrawer() {
        startAnimation(0, mDrawer.getHeight());
    }

    /**
     * 关闭抽屉
     */
    public void closeDrawer() {
        startAnimation(mDrawer.getHeight(), 0);
    }

    public void openDrawerNoAnim() {
        controlDrawer(mDrawer.getHeight());
    }

    public void closeDrawerNoAnim() {
        controlDrawer(0);
    }

    private void controlDrawer(int value) {
        mScrollHeight = value;
        float scroll = (float) mScrollHeight / mDrawer.getHeight();
        if (mScrollHeight == 0) {
            mBottom.setBackground(mBottomBackground);
        } else {
            mBottom.setBackgroundColor(mBottomBackgroundColor);
        }
        mBottom.getBackground().setAlpha((int) (scroll * 255));
        if (mDragCallback != null) {
            mDragCallback.onDrag(scroll);
        }
        // mScrollHeight 改变之后重绘
        requestLayout();
    }

    private void startAnimation(int index, int maxValue) {
        ValueAnimator anim = ValueAnimator.ofInt(index, maxValue);
        anim.setRepeatCount(0);
        anim.setRepeatMode(ValueAnimator.RESTART);
        anim.setDuration(500);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int value = (int) valueAnimator.getAnimatedValue();
                controlDrawer(value);
            }
        });
        anim.start();
    }

    /**
     * 抽屉布局是否展开
     */
    public boolean isDrawerOpened() {
        if (mScrollHeight == mDrawer.getHeight()) {
            return true;
        }
        return false;
    }

    private onDragCallback mDragCallback;

    public void setOnDragCallback(onDragCallback dragCallback) {
        this.mDragCallback = dragCallback;
    }

    public interface onDragCallback {
        void onDrag(float scroll); // scroll: 0-1
    }
}
